package com.zlt.appparking.service.impl;

import com.zlt.appparking.dto.AppUserDTO;
import com.zlt.appparking.entity.AppUser;
import com.zlt.appparking.entity.AppUserExample;
import com.zlt.appparking.entity.UserWallet;
import com.zlt.appparking.entity.UserWalletExample;
import com.zlt.appparking.mapper.AppUserMapper;
import com.zlt.appparking.mapper.UserWalletMapper;
import com.zlt.appparking.service.AppUserService;
import com.zlt.appparking.shiro.config.JWTToken;
import com.zlt.appparking.utils.JWTUtil;
import com.zlt.appparking.utils.MD5Util;
import com.zlt.appparking.utils.StringUtil;
import com.zlt.appparking.vo.ActiveUser;
import com.zlt.appparking.vo.UserWalletVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;


@Service
@Slf4j
public class AppUserServiceImpl implements AppUserService {


    private AppUserService appUserService;

    @Autowired
    @Lazy
    public void setUserService(AppUserService appUserService) {
        this.appUserService = appUserService;
    }

    @Autowired
    private RedisTemplate redisTemplate;


    @Autowired
    private AppUserMapper appUserMapper;

    @Autowired
    private UserWalletMapper userWalletMapper;


    @Override
    public String login(AppUserDTO appUserDTO) {
        String phone = appUserDTO.getAuPhone();
//        AppUser appUser = selectAppUserByPhone(phone);
        AppUser appUser = appUserService.selectAppUserByPhone(phone);
        System.out.println("loginAppUser: " + appUser);
        if (appUser == null) {
            throw new RuntimeException("账号或密码错误");
        }
        String s = MD5Util.md5(appUserDTO.getAuPassword(), appUser.getAuSalt(), 10);
        if (!s.equals(appUser.getAuPassword())) {
            throw new RuntimeException("账号或密码错误");
        }
        String token = JWTUtil.sign(appUser.getAuUsername(), appUser.getAuPassword());
        //校验一次token
        SecurityUtils.getSubject().login(new JWTToken(token));
        return token;

    }

    @Override
    @Cacheable(value = "zltredis", keyGenerator = "appUserKeyGenerator")
    public AppUser selectAppUserByPhone(String phone) {
        AppUserExample appUserExample = new AppUserExample();
        appUserExample.createCriteria().andAuPhoneEqualTo(phone);
        List<AppUser> appUsers = appUserMapper.selectByExample(appUserExample);
        System.out.println("selectAppUsers: " + appUsers);
        return appUsers.isEmpty() ? null : appUsers.get(0);
    }

    @Override
    @Cacheable(value = "zltredis", keyGenerator = "appUserKeyGenerator")
    public AppUser selectAppUserByUsername(String username) {
        AppUserExample appUserExample = new AppUserExample();
        appUserExample.createCriteria().andAuUsernameEqualTo(username);
        List<AppUser> appUsers = appUserMapper.selectByExample(appUserExample);
        System.out.println("appUsers: " + appUsers);
        System.out.println("appUsers: " + appUsers.get(0));

        return appUsers.isEmpty() ? null : appUsers.get(0);
    }

    @Override
    public boolean updateAppUser(AppUserDTO appUserDTO) {
        log.debug("修改用户数据{}", appUserDTO);

        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        if (activeUser == null) {
            throw new RuntimeException("用户未登录");
        }

        AppUser appUser = new AppUser();
        BeanUtils.copyProperties(appUserDTO, appUser);

        int i = appUserMapper.updateByPrimaryKeySelective(appUser);


        return i > 0;
    }

    @Override
    public boolean reg(AppUserDTO appUserDTO) {

        AppUser appUser = new AppUser();
        BeanUtils.copyProperties(appUserDTO, appUser);
        System.out.println(appUser.getAuPhone());

        //手机号唯一
        AppUser phone = appUserService.selectAppUserByPhone(appUser.getAuPhone());
        System.out.println("reg phone:" + phone);
        if (phone != null) {
            return false;
        }

        //设置参数
        appUser.setAuSalt(StringUtil.randomStr(6));
        appUser.setAuState((byte) 0);
        appUser.setAuNickname(StringUtil.randomStr(6));
        appUser.setAuId(StringUtil.uuid());
        appUser.setAuUsername(StringUtil.randomStr2(10));

        //密码加密
        appUser.setAuPassword(MD5Util.md5(appUser.getAuPassword(), appUser.getAuSalt(), 10));

        int i = appUserMapper.insertSelective(appUser);
        if (!(i > 0)) {
            return false;
        }

        //注册用户成功后 给用户一个钱包 并初始化

        UserWallet userWallet = new UserWallet();
        userWallet.setUwMoney(BigDecimal.valueOf(0));
        userWallet.setAuId(appUser.getAuId());

        int j = userWalletMapper.insertSelective(userWallet);


        return j > 0;
    }

    @Override
    public List<UserWalletVO> selectUserWalletByAuId(String auId) {

        UserWalletExample userWalletExample = new UserWalletExample();
        userWalletExample.createCriteria().andAuIdEqualTo(auId);

        List<UserWallet> userWallets = userWalletMapper.selectByExample(userWalletExample);
        List<UserWalletVO> userWalletVOS = new ArrayList<>();

        userWallets.forEach(u -> {
            UserWalletVO userWalletVO = new UserWalletVO();
            BeanUtils.copyProperties(u, userWalletVO);
            userWalletVOS.add(userWalletVO);
        });
        return userWalletVOS;
    }

    @Override
    public boolean updateAppUserPassword(AppUserDTO appUserDTO) {

        //查找对应手机号的用户
        AppUser appUser = appUserService.selectAppUserByPhone(appUserDTO.getAuPhone());
        System.out.println("appUser phone:" + appUser);
        if (appUser == null) {
            return false;
        }
        appUser.setAuPassword(MD5Util.md5(appUserDTO.getAuPassword(), appUser.getAuSalt(), 10));

        int i = appUserMapper.updateByPrimaryKeySelective(appUser);

        return i > 0;
    }
}
